﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using Zbc.Utilities;

namespace Zbc.UserControl
{
    [ToolboxItem(true)]
    [Designer(typeof(SmartTagDesigner))]
    [ToolboxBitmap(typeof(ContextMenuStrip))]
    public partial class CustomMenuStrip : Component
    {
        [Description("背景色")]
        public Color BackColor
        {
            get;set;
        }
        [Description("边线颜色")]
        public Color BoderColor { get; set; }
        [Description("字体颜色")]
        public Color ForeColor { get; set; }
        [Description("对象的名称")]
        public string Name { get; set; }
        [Description("选中状态背景色")]
        public Color SelectBackColor { get; set; }
        [Description("选中状态字体颜色")]
        public Color SelectColor { get; set; }
        [Description("阴影范围")]
        public int ShadowSize { get; set; }
        [DefaultValue(true)]
        [Description("是否显示边线")]
        public bool ShowBorder { get; set; }
        [DefaultValue(true)]
        [Description("是否显示阴影")]
        public bool ShowShadow { get; set; }
        [Description("与对象关联的数据")]
        [TypeConverter(typeof(StringConverter))]
        public object Tag { get; set; }
        [Description("与对象关联的文本")]
        public string Text { get; set; }
        /// <summary>
        /// 文本保留宽度
        /// </summary>
        [Description("文本保留宽度(除文本长度以外多占用的长度，用来调整菜单宽度)")]
        public int TextWidthSp { get; set; }
        /// <summary>
        /// 文本保留高度
        /// </summary>
        [Description("文本保留高度(除文本字体高度以外多占用的高度，用来调整菜单项高度)")]
        public int TextHeightSp { get; set; }
        /// <summary>
        /// 快捷键保留宽度
        /// </summary>
        [Description("快捷键文本保留宽度(除文本长度以外多占用的宽度，用来调整菜单宽度)")]
        public int QuickKeyWidthSp { get; set; }
        /// <summary>
        /// 图片所占宽度
        /// </summary>
        [Description("菜单项图标占用宽度，和图标大小无关")]
        public int ImageWidth { get; set; }
        public Font Font { get; set; }
        /// <summary>
        /// 菜单集合
        /// </summary>
        [Description("菜单项集合"),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public MenuItemCollection Items
        {
            get;
            private set;
        }
        /// <summary>
        /// 鼠标经过颜色
        /// </summary>
        [Description("鼠标经过颜色")]
        public Color HoverColor { get; set; }
        /// <summary>
        /// 多级菜单箭头颜色
        /// </summary>
        [Description("小箭头颜色")]
        public Color ArrowColor { get; set; }
        /// <summary>
        /// 多级菜单鼠标经过箭头颜色
        /// </summary>
        [Description("小箭头选中颜色")]
        public Color ArrowHoverColor { get; set; }
        [Description("无效化时字体颜色")]
        public Color DisableFontColor { get; set; }
        [TypeConverter(typeof(ExpandableObjectConverter)),
        Description("展开以编辑文字排列方式")]
        public StringFormat Format { get; set; }
        [Description("勾的颜色")]
        public Color MarkColor { get; set; }
        [Description("菜单图标大小,图片不等于此大小会自动拉伸或收缩")]
        public Size ImageSize { get; set; }
        /// <summary>
        /// 鼠标点击事件
        /// </summary>
        [Description("鼠标单击事件")]
        public event Action<TextMenuItem> ItemClicked;
        [Description("Check改变事件")]
        public event Action<TextMenuItem> CheckChanged;

        GdiForm gdiForm;

        internal Color ShadeColor = Color.FromArgb(60, Color.Black);
        MenuItemBase m_CurrentItem;
        /// <summary>
        /// 当前选中菜单
        /// </summary>
        public const int EXPAND_LENGTH = 0;
        MenuItemCollection m_HoverMenuItems;

        public CustomMenuStrip()
        {
            InitializeComponent();
            InitStyle();
            InitGdiForm();
        }

        private void InitStyle()
        {
            Items = new MenuItemCollection();
            Items.MenuStrip = this;
            Font = new Font("微软雅黑", 9);
            ShadowSize = 7;
            TextWidthSp = 30;
            TextHeightSp = 10;
            QuickKeyWidthSp = 10;
            ImageWidth = 32;
            ForeColor = Color.FromArgb(40, 40, 40);
            MarkColor = Color.FromArgb(60, 60, 60);
            BackColor = Color.FromArgb(240, 240, 240);
            HoverColor = Color.FromArgb(220, 220, 220);
            BoderColor = Color.FromArgb(201, 201, 201);
            ArrowColor = Color.FromArgb(153, 153, 153);
            DisableFontColor = Color.FromArgb(109, 109, 109);
            ArrowHoverColor = Color.FromArgb(20, 132, 244);
            ImageSize = new Size(16, 16);
            Format = new StringFormat();
            Format.Alignment = StringAlignment.Near;
            Format.LineAlignment = StringAlignment.Center;
            ShowShadow = true;
        }

        public void Hide()
        {
            gdiForm.Hide();
        }

        private void InitGdiForm()
        {
            gdiForm = new GdiForm();
            gdiForm.ShowInTaskbar = false;
            gdiForm.Draw += gidForm_Draw;
            gdiForm.MouseMove += gdiForm_MouseMove;
            gdiForm.MouseUp += gdiForm_MouseUp;
            gdiForm.LostFocus += gdiForm_LostFocus;
            gdiForm.WindowState = FormWindowState.Maximized;
            gdiForm.Refresh();
        }

        private void gidForm_Draw(object sender, PaintEventArgs e)
        {
            Items.Draw(e.Graphics, this);
        }

        void gdiForm_LostFocus(object sender, EventArgs e)
        {
            gdiForm.Hide();
        }

        void gdiForm_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && m_CurrentItem is TextMenuItem)
            {
                TextMenuItem menuItem = m_CurrentItem as TextMenuItem;
                if (menuItem.Enabled && menuItem.Items.Count == 0)
                {
                    if (ItemClicked != null)
                        ItemClicked(menuItem);
                    menuItem.OnClick();
                }
            }
        }

        void gdiForm_MouseMove(object sender, MouseEventArgs e)
        {
            GetCurrentItems(Items);
            foreach (MenuItemBase item in m_HoverMenuItems)
            {
                if (item is TextMenuItem)
                {
                    var menuItem = item as TextMenuItem;
                    menuItem.Selected = false;
                    if (menuItem.Bounds.Contains(Control.MousePosition))
                    {
                        menuItem.Selected = true;
                        m_CurrentItem = menuItem;
                        foreach (MenuItemBase childItem in menuItem.Items)
                        {
                            childItem.Selected = false;
                        }
                    }
                }
            }
            gdiForm.Refresh();
        }

        //递归遍历菜单，找到鼠标当前所在菜单
        private void GetCurrentItems(MenuItemCollection items)
        {
            if (PathHelper.ExpandRect(items.Bounds, ShadowSize).Contains(Control.MousePosition))
            {
                m_HoverMenuItems = items;
            }
            foreach (MenuItemBase item in items)
            {
                if (item is TextMenuItem)
                {
                    var it = item as TextMenuItem;
                    if (it.Selected)
                        GetCurrentItems(it.Items);
                }
            }
        }
        public void Show(IWin32Window w)
        {
            var pt = new Point(Control.MousePosition.X + EXPAND_LENGTH, Control.MousePosition.Y + EXPAND_LENGTH);
            Show(w, pt);
        }

        public void Show(IWin32Window w, Point pt)
        {
            Items.CalcBounds(pt, this);
            gdiForm.Visible = false;
            gdiForm.Refresh();
            gdiForm.Show(w);
            //gdiForm.TopMost = true;
        }

        public void OnCheckChanged(TextMenuItem obj)
        {
            if (CheckChanged != null)
            {
                CheckChanged(obj);
            }
        }
    }
}
